package github.ziwukun.jsonql.lang;

import java.io.Serializable;
import java.util.List;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;

/**
 * where实现类
 * @author Hugo.Yu
 */
public class WhereImpl implements Where{
	private static final long serialVersionUID = 5490981163201012363L;
	String key;
	Serializable val;
	int deep;
	
	WhereImpl(String key,Serializable val){
		this.key = key;
		this.val = ObjectUtil.clone(val);
		asserts();
	}

	@Override
	public String key() {
		return key;
	}

	@Override
	public Object value() {
		return ObjectUtil.cloneByStream(val);
	}

	@Override
	public int deep() {
		return deep;
	}

	@Override
	public boolean keyIsProp() {
		return !CmpOpr.isCmpOpr(key);
	}

	@Override
	public boolean keyIsLogic() {
		return CmpOpr.AND.atWord().equals(this.key) || 
			CmpOpr.OR.atWord().equals(this.key);
	}
	
	@Override
	public boolean keyIsAnd() {
		return CmpOpr.AND.atWord().equals(this.key);
	}

	@Override
	public boolean keyIsOr() {
		return CmpOpr.OR.atWord().equals(this.key);
	}
	
	@Override
	public boolean keyIsCmpOpr() {
		return CmpOpr.isCmpOpr(key);
	}

	@Override
	public CmpOpr keyAsCmpOpr() {
		if(!keyIsCmpOpr()) {
			throw new RuntimeException(key + "不是比较符号");
		}
		
		return CmpOpr.valOf(key);
	}

	@Override
	public String keyAsProp() {
		if(!keyIsProp()) {
			throw new RuntimeException(key + "不是属性名称");
		}
		return key;
	}

	@Override
	public Where valAsWhere() {
		if(val instanceof Where) {
			return ObjectUtil.cloneByStream((Where)val);
		}
		throw new JSONQLBuildException("值类型不是Where");
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Where> valAsWheres() {
		if(!(val instanceof List)) {
			throw new JSONQLBuildException("值类型不是List");
		}
		@SuppressWarnings("rawtypes")
		List<Object> list = (List)val;
		for(Object var : list) {
			if(!(var instanceof Where)) {
				throw new JSONQLBuildException("元素类型不是Where");
			}
		}
		
		return ObjectUtil.cloneByStream((List<Where>) val);
	}

	@Override
	public boolean hasChildProp() {
		if(!(val instanceof Where)) {
			return false;
		}
		Where valWhere = (Where)val;
		if(valWhere.keyIsProp() || valWhere.keyIsLogic()) {
			return true;
		}
		return false;
	}

	@Override
	public Where childPropWhere(String propName) {
		if(StrUtil.isBlank(propName)) {
			return null;
		}
		if(!hasChildProp()) {
			return null;
		}
		Where valWhere = (Where)val;
		if(valWhere.keyIsProp() && valWhere.keyAsProp().equals(propName)) {
			return ObjectUtil.cloneByStream(valWhere);
		}
		else if(valWhere.keyIsLogic()) {
			List<Where> wheres = valWhere.valAsWheres();
			for(Where w : wheres) {
				if(w.keyIsProp() && w.keyAsProp().equals(propName)) {
					return ObjectUtil.cloneByStream(w);
				}
			}
			return null;
		}
		else {
			return null;
		}
	}

	@Override
	public boolean isPropWhere(String propName) {
		if(StrUtil.isBlank(propName)) {
			return false;
		}
		if(!keyIsProp()) {
			return false;
		}
		return key.equals(propName);
	}

	@Override
	public Where propWhere(String propName) {
		if(keyIsProp() && key.equals(propName)) {
			return ObjectUtil.cloneByStream(this);
		}
		else if(keyIsLogic()) {
			List<Where> wheres = valAsWheres();
			for(Where w : wheres) {
				if(w.keyIsProp() && w.key().equals(propName)) {
					return ObjectUtil.cloneByStream(w);
				}
			}
			return null;
		}
		else {
			return null;
		}
	}

	@Override
	public Where replaceProp(String newPropName) {
		WhereImpl newWhere = ObjectUtil.cloneByStream(this);
		newWhere.key = newPropName;
		
		if(!newWhere.keyIsProp()) {
			return null;
		}
		newWhere.asserts();
		return newWhere;
	}

	@Override
	public Where replaceVal(Serializable val) {
		WhereImpl newWhere = ObjectUtil.cloneByStream(this);
		newWhere.val = ObjectUtil.clone(val);
		newWhere.asserts();
		
		return newWhere;
	}

	
	@Override
	public String toJSONQL() {
		return WhereJson.writeJson(this);
	}
	
	// 数据完整性检查
	private void asserts() {
		if(StrUtil.isBlank(key)) {
			throw new JSONQLBuildException("Where对象key不能是空字符串");
		}
		if(val == null) {
			throw new JSONQLBuildException("Where对象val不能是空");
		}
		
		if(keyIsProp()) {
			if(!(val instanceof Where)) {
				throw new JSONQLBuildException("Where语句是属性Where语句，val类型必须是Where类型");
			}
		}
		else if(keyIsCmpOpr()) {
			if(!keyAsCmpOpr().support(val)) {
				throw new JSONQLBuildException(key + "不支持的数据类型" + val.getClass().getSimpleName());
			}
		}
	}
}
